package com.huamoxi.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huamoxi.consts.RedisConst;
import com.huamoxi.consts.ResponseConst;
import com.huamoxi.entity.Dictionary;
import com.huamoxi.entity.LoginRecord;
import com.huamoxi.entity.SysList;
import com.huamoxi.entity.User;
import com.huamoxi.mapper.UserMapper;
import com.huamoxi.result.Result;
import com.huamoxi.service.DictionaryService;
import com.huamoxi.service.LoginRecordService;
import com.huamoxi.service.SysListService;
import com.huamoxi.service.UserService;
import com.huamoxi.utils.CacheUtil;
import com.huamoxi.utils.JwtUtil;
import com.huamoxi.utils.ResultUtil;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
    @Resource
    private AuthenticationManager authenticationManager;

    @Resource
    private UserMapper userMapper;

    @Resource
    private LoginRecordService loginRecordService;

    @Resource
    private SysListService sysListService;

    @Resource
    private DictionaryService dictionaryService;

    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private CacheUtil cacheUtil;

    @Value("${jwt.expiration}")
    private Long expiration;

    @Override
    public Result login(User user, HttpServletRequest request) {
        Date now = new Date();
        String userAgent = request.getHeader("User-Agent");

        // 查询系统
        SysList system = sysListService.getOne(Wrappers.<SysList>lambdaQuery().eq(SysList::getId, user.getSystemId()));
        if (system == null) {
            return ResultUtil.fail("未找到系统");
        }

        // 查询登录失败记录
        LoginRecord loginRecord = loginRecordService.getOne(
                Wrappers.<LoginRecord>lambdaQuery()
                        .eq(LoginRecord::getAccount, user.getAccount())
                        .eq(LoginRecord::getSystemId, user.getSystemId())
        );

        if (loginRecord != null && loginRecord.getLoginFailTimes() == 5) {
            return ResultUtil.fail(ResponseConst.ERR_LOGIN_ACCOUNT_LOCKED);
        }

        try {
            // 进行用户身份验证
            authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getAccount(), user.getPassword()));

            // token 额外携带的信息
            Map<String, Object> claims = new HashMap<>();
            User usr = userMapper.findUserByAccount(user.getAccount());
            if (usr != null) {
                claims.put("id", usr.getId());
                claims.put("phone", usr.getPhone());
                claims.put("nickName", usr.getNickName());
                claims.put("name", usr.getName());
                claims.put("address", usr.getAddress());
                claims.put("email", usr.getEmail());
                claims.put("status", usr.getStatus());
                claims.put("systemId", usr.getSystemId());

                // JWT 生成 Token
                String token = jwtUtil.generateToken(user.getAccount(), claims);

                // token 存入缓存 24小时
                cacheUtil.set(RedisConst.TOKEN_CACHE_KEY_PREFIX + usr.getId(), token, expiration);

                // 更新登录记录
                if (loginRecord == null) {
                    loginRecord = new LoginRecord();
                    loginRecord.setLoginFailTimes(1);
                    loginRecord.setAccount(user.getAccount());
                    loginRecord.setLastLoginTime(now);
                    loginRecord.setSystemId(user.getSystemId());
                    loginRecord.setCreateTime(now);
                    loginRecord.setUpdateTime(now);

                    // 检查请求来源
                    if (userAgent.contains("Tablet") || userAgent.contains("iPad")) {
                        loginRecord.setLastLoginSystem("平板");
                    } else {
                        boolean flag = userAgent.contains("Mobile") || userAgent.contains("Android") || userAgent.contains("iPhone");
                        if (flag) {
                            loginRecord.setLastLoginSystem("手机");
                        } else {
                            loginRecord.setLastLoginSystem("电脑");
                        }
                    }
                }
                loginRecord.setLoginFailTimes(0);
                loginRecordService.saveOrUpdate(loginRecord);

                return ResultUtil.success("登录成功", token);
            }
            return ResultUtil.fail(ResponseConst.BAD_LOGIN_CODE, ResponseConst.ERR_LOGIN_NO_ACCOUNT);
        } catch (Exception e) {
            if (e instanceof BadCredentialsException) {
                if (loginRecord != null) {
                    Dictionary maxErrLogin = dictionaryService.getOne(
                            Wrappers.<Dictionary>lambdaQuery()
                                    .eq(Dictionary::getFiled, "max_err_login")
                                    .eq(Dictionary::getSystemId, user.getSystemId())
                    );
                    if (loginRecord.getLoginFailTimes() < Integer.parseInt(maxErrLogin.getValue())) {
                        // 登录失败次数 + 1
                        loginRecord.setLoginFailTimes(loginRecord.getLoginFailTimes() + 1);
                        loginRecord.setLastLoginTime(now);
                        loginRecord.setUpdateTime(now);
//                    loginRecord.setLastLoginIp();
//                    loginRecord.setLastLoginAddress();

                        // 检查请求来源
                        if (userAgent.contains("Tablet") || userAgent.contains("iPad")) {
                            loginRecord.setLastLoginSystem("平板");
                        } else {
                            boolean flag = userAgent.contains("Mobile") || userAgent.contains("Android") || userAgent.contains("iPhone");
                            if (flag) {
                                loginRecord.setLastLoginSystem("手机");
                            } else {
                                loginRecord.setLastLoginSystem("电脑");
                            }
                        }
                    }
                }
                if (loginRecord == null) {
                    loginRecord = new LoginRecord();
                    loginRecord.setLoginFailTimes(1);
                    loginRecord.setAccount(user.getAccount());
                    loginRecord.setLastLoginTime(now);
                    loginRecord.setSystemId(user.getSystemId());
                    loginRecord.setCreateTime(now);
                    loginRecord.setUpdateTime(now);

                    // 检查请求来源
                    if (userAgent.contains("Tablet") || userAgent.contains("iPad")) {
                        loginRecord.setLastLoginSystem("平板");
                    } else {
                        boolean flag = userAgent.contains("Mobile") || userAgent.contains("Android") || userAgent.contains("iPhone");
                        if (flag) {
                            loginRecord.setLastLoginSystem("手机");
                        } else {
                            loginRecord.setLastLoginSystem("电脑");
                        }
                    }
                }
                loginRecordService.saveOrUpdate(loginRecord);

                return ResultUtil.fail(ResponseConst.BAD_LOGIN_CODE, e.getMessage());
            }
            return ResultUtil.fail(ResponseConst.BAD_LOGIN_CODE, ResponseConst.ERR_LOGIN_MESSAGE);
        }
    }
}
